package org.wang.generalcode.modules.sys.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.wang.generalcode.modules.sys.converter.UserConverter;
import org.wang.generalcode.modules.sys.excel.UserExportDTO;
import org.wang.generalcode.modules.sys.excel.UserImportDTO;
import org.wang.generalcode.modules.sys.excel.UserImportListener;
import org.wang.generalcode.modules.sys.pojo.params.UserParams;
import org.wang.generalcode.modules.sys.pojo.entity.User;
import org.wang.generalcode.modules.sys.pojo.params.UserPageParams;
import org.wang.generalcode.modules.sys.pojo.entity.UserRole;
import org.wang.generalcode.modules.sys.pojo.vo.UserPageVO;
import org.wang.generalcode.modules.sys.service.IUserRoleService;
import org.wang.generalcode.modules.sys.service.IUserService;
import org.wang.generalcode.modules.sys.pojo.vo.UserVO;
import org.wang.generalcode.modules.sys.util.ExcelUtils;
import org.wang.generalcode.support.mybaties.Condition;
import org.wang.generalcode.support.mybaties.Query;
import org.wang.generalcode.support.result.Result;
import org.wang.generalcode.support.utils.Func;

import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 用户信息表 控制器
 *
 * @author wz
 * @since 2024-08-08
 */
@RestController
@AllArgsConstructor
@RequestMapping("/user")
@Schema(description = "用户信息表", name = "用户信息表接口")
public class UserController {

	private final IUserService userService;

	private final UserConverter userConverter;

	private final IUserRoleService userRoleService;


	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@Schema(description = "详情", example = "传入user")
	public Result<UserParams> detail(User user) {
		User detail = userService.getOne(Condition.getQueryWrapper(user));
		UserParams form = userConverter.toForm(detail);
		List<UserRole> list = userRoleService.list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, detail.getId()));
		form.setRoleIds(list.stream().map(UserRole::getRoleId).toList());
		return Result.success(form);
	}

	/**
	 * 分页 用户信息表
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@Schema(description = "分页", example = "传入user")
	public Result<IPage<User>> list(User user, Query query) {
		IPage<User> pages = userService.page(Condition.getPage(query), Condition.getQueryWrapper(user));
		return Result.success(pages);
	}

	/**
	 * 自定义分页 用户信息表
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@Schema(description = "分页", example = "传入user")
	public Result<IPage<UserPageVO>> page(UserPageParams queryParams, Query query) {
		IPage<UserPageVO> pages = userService.selectUserPage(Condition.getPage(query), queryParams);
		return Result.success(pages);
	}

	/**
	 * 新增 用户信息表
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@Schema(description = "新增", example = "传入user")
	public Result save(@Valid @RequestBody UserParams userParams) {
		return Result.judge(userService.saveUser(userParams));
	}

	/**
	 * 修改 用户信息表
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@Schema(description = "修改", example = "传入user")
	public Result update(@Valid @RequestBody UserParams userParams) {
		return Result.judge(userService.updateUser(userParams));
	}


	/**
	 * 获取当前登录用户信息
	 */
	@GetMapping("/me")
	@ApiOperationSupport(order = 6)
	@Schema(description = "获取当前登录用户信息", example = "")
	public Result<UserVO> getCurrentUserInfo() {
		UserVO userVO = userService.getCurrentUserInfo();
		return Result.success(userVO);
	}

	/**
	 * 用户导入模板下载
	 */
	@GetMapping("/template")
	@ApiOperationSupport(order = 7)
	@Schema(description = "用户导入模板下载", example = "")
	public void downloadTemplate(HttpServletResponse response) throws IOException {
		String fileName = "用户导入模板.xlsx";
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));

		String fileClassPath = "templates" + File.separator + "excel" + File.separator + fileName;
		InputStream inputStream =getClass().getResourceAsStream(fileClassPath);

		ServletOutputStream outputStream = response.getOutputStream();
		ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(inputStream).build();

		excelWriter.finish();
	}

	/**
	 * 导入用户
	 */
	@PostMapping("/import")
	@ApiOperationSupport(order = 8)
	@Schema(description = "导入用户", example = "传入ids")
	public Result<?> importUsers(MultipartFile file) throws IOException{
		UserImportListener listener = new UserImportListener();
		String msg = ExcelUtils.importExcel(file.getInputStream(), UserImportDTO.class, listener);
		return Result.success(msg);
	}


	/**
	 * 导出用户
	 */
	@GetMapping("/export")
	@ApiOperationSupport(order = 9)
	@Schema(description = "导出用户", example = "")
	public void exportUsers(UserPageParams queryParams, HttpServletResponse response) throws IOException {
		String fileName = "用户列表.xlsx";
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));

		List<UserExportDTO> exportUserList = userService.listExportUsers(queryParams);
		EasyExcel.write(response.getOutputStream(), UserExportDTO.class).sheet("用户列表")
				.doWrite(exportUserList);
	}


	/**
	 * 删除 用户信息表
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 10)
	@Schema(description = "删除", example = "传入ids")
	public Result remove(@Parameter(name = "主键集合", required = true) @RequestParam String ids) {
		return Result.judge(userService.removeByIds(Func.toLongList(ids)));
	}




}
